package jastgen.generator;

import java.io.PrintWriter;

public class ComparableImplBodyGenerator implements BodyGenerator {

	@Override
	public void generate(final PrintWriter out) {

		out.println("/**");
		out.println(" * 抽象クラスがComparableを実装し、サブクラス間で比較を行う場合に使用する。");
		out.println(" * ");
		out.println(" * @author ac_zero");
		out.println(" *");
		out.println(" * @param <T> 「extends ComparableImpl」を宣言するクラス自身");
		out.println(" */");
		out.println("public abstract class ComparableImpl<T extends ComparableImpl<T>>");
		out.println("	implements Comparable<T>");
		out.println("{");
//		out.println("	// TODO: finalは後で外す");
		out.println("	@Override");
		out.println("	public final int compareTo(");
		out.println("			final T rhs)");
		out.println("	{");
		out.println("		if(this == rhs)");
		out.println("			return EQ;");
		out.println("		final int azh =     ordinal();");
		out.println("		final int bzh = rhs.ordinal();");
		out.println("		if(azh < bzh)");
		out.println("			return LT;");
		out.println("		if(azh > bzh)");
		out.println("			return GT;");
		out.println("		return compareToImpl(rhs);");
		out.println("	}");
		out.println();
		out.println("	/**");
		out.println("	 * 引数を即座にサブクラス (このメソッドを実装する具象クラス自身) に");
		out.println("	 * キャストし、同じクラスのオブジェクト間での比較を行う。");
		out.println("	 * ");
		out.println("	 * @param rhs");
//		out.println("	 * @return compareToの返値と同様");
		out.println("	 * @return Same as return value of compareTo.");
		out.println("	 */");
		out.println("	protected abstract int compareToImpl(T rhs);");
		out.println();
		out.println("	/**");
		out.println("	 * 型引数のサブクラス間で、クラス単位の順序を定義する。");
		out.println("	 * 重複してはならない。");
		out.println("	 * (重複した場合、compareToImpl冒頭のキャストで例外が投げられる)");
		out.println("	 * ");
		out.println("	 * @return クラス単位の順序");
		out.println("	 */");
		out.println("	protected abstract int ordinal();");
		out.println("}");
	}
}
